using System;
using System.Collections.Generic;
using System.Deployment.Application;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Microsoft.Win32;

namespace VisualStudioMruFileUtil
{
   public partial class MainForm : Form
   {
      private MruManager activeManager;
      private int fullFileIndex;

      public MainForm()
      {
         InitializeComponent();
         PopulateVersionList();
      }

      private void PopulateVersionList()
      {
         MruManager mgr2003 = new MruManager(VisualStudioVersion.VisualStudio2003);
         MruManager mgr2005 = new MruManager(VisualStudioVersion.VisualStudio2005);
         MruManager mgr2008 = new MruManager(VisualStudioVersion.VisualStudio2008);
         MruManager mgr2010 = new MruManager(VisualStudioVersion.VisualStudio2010);

         if (CheckForMruListByVersion(mgr2005))
         {
            comboBoxVersion.Items.Add(mgr2005);
            comboBoxVersion.SelectedItem = mgr2005;
         }

         if (CheckForMruListByVersion(mgr2003))
         {
            comboBoxVersion.Items.Add(mgr2003);
            comboBoxVersion.SelectedItem = mgr2003;
         }

         if (CheckForMruListByVersion(mgr2010))
         {
            comboBoxVersion.Items.Add(mgr2010);
            comboBoxVersion.SelectedItem = mgr2010;
         }

         if (CheckForMruListByVersion(mgr2008))
         {
            comboBoxVersion.Items.Add(mgr2008);
            comboBoxVersion.SelectedItem = mgr2008;
         }
         activeManager = (MruManager) comboBoxVersion.SelectedItem;
      }

      private bool CheckForMruListByVersion(MruManager mgr)
      {
         using (RegistryKey key = Registry.CurrentUser.OpenSubKey(mgr.VsVersion.KeyName, false))
         {
            return key != null;
         }
      }

      private void linkLabelClearAll_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
      {
         try
         {
            activeManager.ClearAll();
            RefreshUI();
         }
         catch (Exception ex)
         {
            MessageBox.Show("Error: " + ex.Message, "Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
         }
      }

      private void linkLabelClearMissing_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
      {
         try
         {
            activeManager.ClearMissing();
            RefreshUI();
         }
         catch (Exception ex)
         {
            MessageBox.Show("Error: " + ex.Message, "Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
         }
      }

      private void MainForm_Load(object sender, EventArgs e)
      {
         try
         {
            CheckForUpdateAsync();

            RefreshUI();

            MainPersistentWindowState state = new MainPersistentWindowState(this);
            state.InitializeWindow();

            if (activeManager == null)
            {
               string msg =
                  "It appears that you do not have an installed version of Visual Studio. Run visual studio and try running this program again.";
               MessageBox.Show(msg, "Missing Applications", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
         }
         catch (Exception ex)
         {
            MessageBox.Show("Error: " + ex.Message, "Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
         }
      }

      private void CheckForUpdateAsync()
      {
         if (!ApplicationDeployment.IsNetworkDeployed)
         {
            this.Text += " [Not Deployed]";
            return;
         }

         ApplicationDeployment deploy = ApplicationDeployment.CurrentDeployment;
         if (deploy != null)
         {
            deploy.CheckForUpdateCompleted += deploy_CheckForUpdateCompleted;
            deploy.CheckForUpdateAsync();
         }
      }

      private void deploy_CheckForUpdateCompleted(object sender, CheckForUpdateCompletedEventArgs e)
      {
         if (!e.UpdateAvailable)
            return;

         string msg = "An update is available, Restart the application to install the update.";
         MessageBox.Show(this, msg, "VS Recent Files Utility: Update available", MessageBoxButtons.OK,
                         MessageBoxIcon.Information);
      }

      private void RefreshUI()
      {
         listViewFiles.Items.Clear();
         if (activeManager == null)
         {
            return;
         }

         groupBoxFiles.Text = "Recently Used Projects for " + activeManager;
         List<string> fileList = activeManager.GetRecentFiles();

         fullFileIndex = 4;
         foreach (string file in fileList)
         {
            string[] subItems = new[]
                                   {
                                      "",
                                      IsItemMissing(file) ? "YES" : "",
                                      GetItemSolution(file),
                                      GetItemPath(file),
                                      file
                                   };
            ListViewItem item = new ListViewItem(subItems);
            item.ForeColor = IsItemMissing(file) ? Color.Red : Color.Black;
            listViewFiles.Items.Add(item);
         }

         linkLabelClearMissing.Enabled = activeManager.HasMissingFiles;
         linkLabelClearCsProj.Enabled = activeManager.HasCsProjFiles;
      }

      private bool IsItemMissing(string file)
      {
         return !File.Exists(file);
      }

      private string GetItemSolution(string file)
      {
         file = file.Trim();

         return Path.GetFileName(file);
      }

      private string GetItemPath(string file)
      {
         return Path.GetDirectoryName(file);
      }

      private void linkLabelAbout_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
      {
         new AboutForm().ShowDialog(this);
      }

      private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
      {
         MainPersistentWindowState state = new MainPersistentWindowState(this);
         state.SaveWindow();
      }

      private void comboBoxVersion_SelectedIndexChanged(object sender, EventArgs e)
      {
         activeManager = (MruManager) comboBoxVersion.SelectedItem;
         try
         {
            RefreshUI();
         }
         catch (Exception ex)
         {
            MessageBox.Show("Error: " + ex.Message, "Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
         }
      }

      private void linkLabelClearChecked_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
      {
         try
         {
            List<string> files = new List<string>();
            foreach (ListViewItem item in listViewFiles.Items)
            {
               if (item.Checked)
               {
                  files.Add(item.SubItems[fullFileIndex].Text);
               }
            }
            activeManager.ClearFiles(files.ToArray());
            RefreshUI();
         }
         catch (Exception ex)
         {
            MessageBox.Show("Error: " + ex.Message, "Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
         }
      }

      private void listViewFiles_ItemChecked(object sender, ItemCheckedEventArgs e)
      {
         if (listViewFiles == null || linkLabelClearChecked == null)
         {
            return;
         }

         foreach (ListViewItem item in listViewFiles.Items)
         {
            if (item != null && item.Checked)
            {
               linkLabelClearChecked.Enabled = true;
               return;
            }
         }

         linkLabelClearChecked.Enabled = false;
      }

      private void linkLabelClearCsProj_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
      {
         try
         {
            List<string> files = new List<string>();
            foreach (ListViewItem item in listViewFiles.Items)
            {
               string file = item.SubItems[fullFileIndex].Text;
               if (file.ToLower().EndsWith(".csproj") ||
                  file.ToLower().EndsWith(".vbproj"))
               {
                  files.Add(file);
               }
            }
            activeManager.ClearFiles(files.ToArray());
            RefreshUI();
         }
         catch (Exception exception)
         {
            MessageBox.Show("Error: " + exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
         }
      }
   }
}